/*
 *  $Id: NumberEndingPhrasePart.cs 1180 2010-11-10 14:13:13Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2010 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

namespace Ragima.Languages.PhraseParts {
    /// <summary>
    /// Абстрактная часть фразы окончания, зависящего от числа.
    /// </summary>
    public abstract class NumberEndingPhrasePart : TypedArgPhrasePart<int> {
        private string[] _variants;

        public NumberEndingPhrasePart(int argNum, string[] variants) : base(argNum) {
            _variants = variants;
        }

        /// <summary>
        /// Строит окончание, зависящее от числа.
        /// </summary>
        protected override void BuildArg(PhraseBuilder builder, int arg) {
            int index = GetNumberIndex(arg);
            if (index >= 0 && index < _variants.Length)
                builder.Append(_variants[index]);
        }

        /// <summary>
        /// Получает номер варианта окончания по указанному числу.
        /// </summary>
        public abstract int GetNumberIndex(int arg);

        /// <summary>
        /// Абстрактный парсер для части фразы окончания.
        /// </summary>
        public abstract class NumberEndingParser : IPhrasePartParser {
            public bool NeedArgument {
                get { return true; }
            }

            public bool Test(PhraseTemplateScanner scanner) {
                return scanner.Test(PhraseTemplateSymbols.NumberEndingCommand);
            }

            public PhrasePart Create(int argNum, PhraseTemplateScanner scanner) {
                return Create(argNum, GetVariants(scanner));
            }

            /// <summary>
            /// Получает из шаблона список вариантов окончаний.
            /// </summary>
            private static string[] GetVariants(PhraseTemplateScanner scanner) {
                if (scanner.Test(PhraseTemplateSymbols.NumberEndingCommand))
                    scanner.NextChar();
                if (scanner.Test(PhraseTemplateSymbols.CommandSeparator))
                    scanner.NextChar();
                return scanner.GetCommandText().Split(PhraseTemplateSymbols.VariantSeparator);
            }

            protected abstract PhrasePart Create(int argNum, string[] variants);
        }
    }
}
